package ChatSystem;

import java.net.InetAddress;
import java.util.ArrayList;

import ChatSystem.ChatMessage;

/**
 *  Represents a ChatSystem user, either local or distant
 */
public class User {
	private String _nickname;
	private final ArrayList<ChatMessage> _messages;
	private InetAddress _address;
	private int _port;
	private int _unreadMessages = 0;
	
	/**
	 * Creates a ChatSystem user
	 * @param nickname The user nickname
	 * @param address The user Internet address
	 * @param port The user's ChatSystem's UDP/TCP port
	 */
	User(String nickname, InetAddress address, int port) {
		_nickname = nickname;
		_address = address;
		_port = port;
		
		_messages = new ArrayList<ChatMessage>();
	}
	
	/**
	 * Retrieves the user's nickname
	 * @return The user's nickname
	 */
	public String getNickname() {
		return _nickname;
	}
	
	/**
	 * Retrieves the user's Internet address
	 * @return The user's Internet address
	 */
	public InetAddress getAddress() {
		return _address;
	}
	
	/**
	 * Changes the user's Internet address. Useful as we don't know our address until we receive our first HelloAck message
	 * @param address The user's new Internet address
	 */
	public void setAddress(InetAddress address) {
		_address = address;
	}
	
	/**
	 * Retrieves the users' TCP and UDP port number
	 * @return The TCP/UDP port number
	 */
	public int getPort() {
		return _port;
	}
	
	/**
	 * Gets the list of all received and sent messages of the user.
	 * @return An array of messages sent or received by the user.
	 */
	public ArrayList<ChatMessage> getMessages() {
		return _messages;
	}
	
	/**
	 * Gets the unread messages counter. 0 means that all messages of the conversation have been marked read, whereas a &gt; 0 value means that some messages were received and the local user did not see them.
	 * @return The unread messages counter
	 */
	public int getUnreadCount() {
		synchronized(this) {
			return _unreadMessages;
		}
	}
	
	/**
	 * Adds the message to the user's conversation.
	 * @param msg The message to add to the conversation
	 */
	public void addMessage(ChatMessage msg) {
		synchronized(this) {
			_messages.add(msg);
		}
	}

	/**
	 * Atomically adds the message to the user's conversation, and increases the unread messages counter.
	 * @param msg The message to add to the conversation
	 */
	public void addUnreadMessage(ChatMessage msg) {
		synchronized(this) {
			_messages.add(msg);
			_unreadMessages = _unreadMessages + 1;
		}
	}
	
	/**
	 * Resets the unread messages counter to 0, to mark the whole conversation as read.
	 */
	public void markAsRead() {
		synchronized(this) {
			_unreadMessages = 0;
		}
	}

	/**
	 * Compares this with the given parameter. The comparison is made by Internet address.
	 * @param obj The object to compare against
	 */
	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof User)) {
			return false;
		}
		
		User user = (User)obj;
		
		return _address.equals(user.getAddress()) && _nickname.equals(user.getNickname());
	}
}
